package com.es.easystoragesimulatedata.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.es.easystoragesimulatedata.mapper.StationDataMapper;
import com.es.easystoragesimulatedata.model.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 电站数据服务类
 * 
 * @author EasyStorage
 * @since 2025-01-22
 */
@Slf4j
@Service
public class StationDataService {

    @Autowired
    private StationDataMapper stationDataMapper;
    
    @Autowired
    private StationInfoService stationInfoService;

    /**
     * 保存电站数据
     */
    public boolean saveStationData(StationData stationData) {
        try {
            int result = stationDataMapper.insert(stationData);
            log.info("保存电站数据成功，影响行数: {}", result);
            return result > 0;
        } catch (Exception e) {
            log.error("保存电站数据失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 根据电站ID查询数据
     */
    public List<StationData> getStationDataByStationId(String stationId) {
        LocalDate today = LocalDate.now();
        QueryWrapper<StationData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("station_id", stationId)
                   .le("data_date", today)  // 只查询今天及之前的数据
                   .orderByDesc("data_date");
        return stationDataMapper.selectList(queryWrapper);
    }

    /**
     * 根据日期范围查询数据
     */
    public List<StationData> getStationDataByDateRange(LocalDate startDate, LocalDate endDate) {
        LocalDate today = LocalDate.now();
        QueryWrapper<StationData> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("data_date", startDate, endDate)
                   .le("data_date", today)  // 只查询今天及之前的数据
                   .orderByDesc("data_date");
        return stationDataMapper.selectList(queryWrapper);
    }

    /**
     * 分页查询电站数据
     */
    public Page<StationData> getStationDataPage(int current, int size) {
        LocalDate today = LocalDate.now();
        Page<StationData> page = new Page<>(current, size);
        QueryWrapper<StationData> queryWrapper = new QueryWrapper<>();
        queryWrapper.le("data_date", today)  // 只查询今天及之前的数据
                   .orderByDesc("data_date");
        return stationDataMapper.selectPage(page, queryWrapper);
    }

    /**
     * 更新电站数据
     */
    public boolean updateStationData(StationData stationData) {
        try {
            int result = stationDataMapper.updateById(stationData);
            log.info("更新电站数据成功，影响行数: {}", result);
            return result > 0;
        } catch (Exception e) {
            log.error("更新电站数据失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 删除电站数据（逻辑删除）
     */
    public boolean deleteStationData(Long id) {
        try {
            int result = stationDataMapper.deleteById(id);
            log.info("删除电站数据成功，影响行数: {}", result);
            return result > 0;
        } catch (Exception e) {
            log.error("删除电站数据失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 获取所有电站数据
     */
    public List<StationData> getAllStationData() {
        LocalDate today = LocalDate.now();
        QueryWrapper<StationData> queryWrapper = new QueryWrapper<>();
        queryWrapper.le("data_date", today)  // 只查询今天及之前的数据
                   .orderByDesc("data_date");
        return stationDataMapper.selectList(queryWrapper);
    }

    /**
     * 根据具体日期查询数据
     */
    public List<StationData> getStationDataByDate(LocalDate date) {
        LocalDate today = LocalDate.now();
        QueryWrapper<StationData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("data_date", date)
                   .le("data_date", today)  // 只查询今天及之前的数据
                   .orderByDesc("data_date");
        return stationDataMapper.selectList(queryWrapper);
    }

    /**
     * 根据月份查询数据
     */
    public List<StationData> getStationDataByMonth(int year, int month) {
        LocalDate today = LocalDate.now();
        QueryWrapper<StationData> queryWrapper = new QueryWrapper<>();
        queryWrapper.apply("YEAR(data_date) = {0} AND MONTH(data_date) = {1}", year, month)
                   .le("data_date", today)  // 只查询今天及之前的数据
                   .orderByDesc("data_date");
        return stationDataMapper.selectList(queryWrapper);
    }

    /**
     * 根据电站ID和月份查询数据
     */
    public List<StationData> getStationDataByStationIdAndMonth(String stationId, int year, int month) {
        LocalDate today = LocalDate.now();
        QueryWrapper<StationData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("station_id", stationId)
                   .apply("YEAR(data_date) = {0} AND MONTH(data_date) = {1}", year, month)
                   .le("data_date", today)  // 只查询今天及之前的数据
                   .orderByDesc("data_date");
        return stationDataMapper.selectList(queryWrapper);
    }

    /**
     * 根据年份查询数据
     */
    public List<StationData> getStationDataByYear(int year) {
        LocalDate today = LocalDate.now();
        QueryWrapper<StationData> queryWrapper = new QueryWrapper<>();
        queryWrapper.apply("YEAR(data_date) = {0}", year)
                   .le("data_date", today)  // 只查询今天及之前的数据
                   .orderByDesc("data_date");
        return stationDataMapper.selectList(queryWrapper);
    }

    /**
     * 获取电站排名数据
     * @param dataType 排名数据类型
     * @param sortOrder 排序方式
     * @return 排名数据列表
     */
    public List<StationRanking> getStationRanking(RankingDataType dataType, SortOrder sortOrder) {
        log.info("开始计算电站排名 - 数据类型: {}, 排序方式: {}", dataType, sortOrder);
        
        try {
            // 获取所有电站信息
            List<StationInfo> allStations = stationInfoService.getAllStationInfo();
            
            // 获取所有电站数据
            List<StationData> allStationData = getAllStationData();
            
            // 按电站ID分组，计算每个电站的累计值
            Map<String, List<StationData>> stationDataMap = allStationData.stream()
                .collect(Collectors.groupingBy(StationData::getStationId));
            
            List<StationRanking> rankingList = new ArrayList<>();
            
            // 遍历所有电站，包括没有数据的电站
            for (StationInfo station : allStations) {
                String stationId = station.getStationId();
                String stationName = station.getStationName();
                
                StationRanking ranking = new StationRanking();
                ranking.setStationId(stationId);
                ranking.setStationName(stationName);
                ranking.setUnit(getUnit(dataType));
                
                // 检查是否有数据
                List<StationData> stationDataList = stationDataMap.get(stationId);
                if (stationDataList != null && !stationDataList.isEmpty()) {
                    // 根据数据类型计算累计值
                    Double totalValue = calculateTotalValue(stationDataList, dataType);
                    if (totalValue != null && totalValue > 0) {
                        // 格式化数值，保留2位小数
                        ranking.setValue(Math.round(totalValue * 100.0) / 100.0);
                    } else {
                        ranking.setValue(0.0);
                    }
                } else {
                    // 没有数据，设置为0
                    ranking.setValue(0.0);
                }
                
                rankingList.add(ranking);
            }
            
            // 根据排序方式排序
            if (sortOrder == SortOrder.DESC) {
                rankingList.sort((a, b) -> Double.compare(b.getValue(), a.getValue()));
            } else {
                rankingList.sort((a, b) -> Double.compare(a.getValue(), b.getValue()));
            }
            
            // 设置排名
            for (int i = 0; i < rankingList.size(); i++) {
                rankingList.get(i).setRank(i + 1);
            }
            
            log.info("电站排名计算完成 - 共{}个电站", rankingList.size());
            return rankingList;
            
        } catch (Exception e) {
            log.error("计算电站排名失败: {}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 根据数据类型计算累计值
     */
    private Double calculateTotalValue(List<StationData> stationDataList, RankingDataType dataType) {
        switch (dataType) {
            case DISCHARGE_ENERGY:
                // 储能放电量：累计上网电量
                return stationDataList.stream()
                    .mapToDouble(data -> data.getGridUploadPower() != null ? 
                        data.getGridUploadPower().doubleValue() : 0.0)
                    .sum();
                    
            case SYSTEM_EFFICIENCY:
                // 系统效率：累计上网电量 / 累计下网电量
                double totalUploadPower = stationDataList.stream()
                    .mapToDouble(data -> data.getGridUploadPower() != null ? 
                        data.getGridUploadPower().doubleValue() : 0.0)
                    .sum();
                
                double totalDownloadPower = stationDataList.stream()
                    .mapToDouble(data -> data.getGridDownloadPower() != null ? 
                        data.getGridDownloadPower().doubleValue() : 0.0)
                    .sum();
                
                if (totalDownloadPower > 0) {
                    return (totalUploadPower / totalDownloadPower) * 100; // 转换为百分比
                } else {
                    return 0.0;
                }
                    
            case CUMULATIVE_REVENUE:
                // 储能累计收入：累计收入
                return stationDataList.stream()
                    .mapToDouble(data -> data.getRevenue() != null ? 
                        data.getRevenue().doubleValue() : 0.0)
                    .sum();
                    
            default:
                return 0.0;
        }
    }
    
    /**
     * 获取数值单位
     */
    private String getUnit(RankingDataType dataType) {
        switch (dataType) {
            case DISCHARGE_ENERGY:
                return "MWh";
            case SYSTEM_EFFICIENCY:
                return "%";
            case CUMULATIVE_REVENUE:
                return "万元";
            default:
                return "";
        }
    }
    
    /**
     * 获取仪表板数据
     * @return 仪表板数据
     */
    public DashboardData getDashboardData() {
        log.info("开始获取仪表板数据");
        
        try {
            // 获取电站分布数据
            StationDistribution stationDistribution = getStationDistribution();
            
            // 获取电站状态数据
            StationStatusStats stationStatus = getStationStatus();
            
            // 获取工单状态数据（写死的数据）
            WorkOrderStatus workOrderStatus = getWorkOrderStatus();
            
            // 获取收入统计数据
            IncomeStatistics incomeStatistics = getIncomeStatistics();
            
            // 获取社会效益数据
            SocialBenefit socialBenefit = getSocialBenefit();
            
            DashboardData dashboardData = new DashboardData();
            dashboardData.setStationDistribution(stationDistribution);
            dashboardData.setStationStatus(stationStatus);
            dashboardData.setWorkOrderStatus(workOrderStatus);
            dashboardData.setIncomeStatistics(incomeStatistics);
            dashboardData.setSocialBenefit(socialBenefit);
            
            log.info("成功获取仪表板数据");
            return dashboardData;
            
        } catch (Exception e) {
            log.error("获取仪表板数据失败: {}", e.getMessage(), e);
            return new DashboardData();
        }
    }
    
    /**
     * 获取电站分布数据
     */
    private StationDistribution getStationDistribution() {
        List<StationInfo> allStations = stationInfoService.getAllStationInfo();
        
        // 计算电站总数
        int totalStations = allStations.size();
        
        // 计算总装机容量
        String totalCapacity = calculateTotalCapacity(allStations);
        
        // 计算各省份分布
        List<ProvinceDistribution> provinceDistribution = calculateProvinceDistribution(allStations);
        
        StationDistribution distribution = new StationDistribution();
        distribution.setTotalStations(totalStations);
        distribution.setTotalCapacity(totalCapacity);
        distribution.setProvinceDistribution(provinceDistribution);
        
        return distribution;
    }
    
    /**
     * 计算总装机容量
     */
    private String calculateTotalCapacity(List<StationInfo> stations) {
        int totalMW = 0;
        int totalMWh = 0;
        
        Pattern pattern = Pattern.compile("(\\d+)MW/(\\d+)MWh");
        
        for (StationInfo station : stations) {
            if (station.getCapacity() != null) {
                Matcher matcher = pattern.matcher(station.getCapacity());
                if (matcher.find()) {
                    totalMW += Integer.parseInt(matcher.group(1));
                    totalMWh += Integer.parseInt(matcher.group(2));
                }
            }
        }
        
        return totalMW + "MW/" + totalMWh + "MWh";
    }
    
    /**
     * 计算各省份分布
     */
    private List<ProvinceDistribution> calculateProvinceDistribution(List<StationInfo> stations) {
        Map<String, Long> provinceCount = stations.stream()
            .collect(Collectors.groupingBy(
                station -> extractProvince(station.getLocation()),
                Collectors.counting()
            ));
        
        int totalCount = stations.size();
        
        return provinceCount.entrySet().stream()
            .map(entry -> {
                ProvinceDistribution distribution = new ProvinceDistribution();
                distribution.setProvince(entry.getKey());
                distribution.setCount(entry.getValue().intValue());
                distribution.setPercentage(Math.round((double) entry.getValue() / totalCount * 10000.0) / 100.0);
                return distribution;
            })
            .sorted((a, b) -> Integer.compare(b.getCount(), a.getCount()))
            .collect(Collectors.toList());
    }
    
    /**
     * 从地理位置中提取省份
     */
    private String extractProvince(String location) {
        if (location == null || location.trim().isEmpty()) {
            return "未知";
        }
        
        // 提取省份（取第一个词）
        String[] parts = location.split("省|市|自治区|特别行政区");
        if (parts.length > 0) {
            return parts[0] + (location.contains("省") ? "省" : 
                             location.contains("自治区") ? "自治区" : 
                             location.contains("特别行政区") ? "特别行政区" : "市");
        }
        
        return location;
    }
    
    /**
     * 获取电站状态数据
     */
    private StationStatusStats getStationStatus() {
        List<StationInfo> allStations = stationInfoService.getAllStationInfo();
        
        int totalCount = allStations.size();
        int gridConnectedCount = 0;
        int commercialOperationCount = 0;
        int constructionCount = 0;
        
        for (StationInfo station : allStations) {
            String status = station.getStatus();
            if ("已并网".equals(status)) {
                gridConnectedCount++;
            } else if ("已商运".equals(status)) {
                commercialOperationCount++;
            } else if ("建设中".equals(status)) {
                constructionCount++;
            }
        }
        
        StationStatusStats stationStatus = new StationStatusStats();
        stationStatus.setTotalCount(totalCount);
        stationStatus.setGridConnectedCount(gridConnectedCount);
        stationStatus.setCommercialOperationCount(commercialOperationCount);
        stationStatus.setConstructionCount(constructionCount);
        
        return stationStatus;
    }
    
    /**
     * 获取工单状态数据（写死的数据）
     */
    private WorkOrderStatus getWorkOrderStatus() {
        WorkOrderStatus workOrderStatus = new WorkOrderStatus();
        workOrderStatus.setTotalOrders(143);
        workOrderStatus.setCompletedOrders(65);
        workOrderStatus.setAbnormalOrders(10);
        workOrderStatus.setOtherOrders(68);
        
        return workOrderStatus;
    }
    
    /**
     * 获取收入统计数据
     */
    private IncomeStatistics getIncomeStatistics() {
        LocalDate today = LocalDate.now();
        int currentYear = today.getYear();
        int currentMonth = today.getMonthValue();
        
        // 计算日收入（当日所有电站的收入）
        List<StationData> todayData = getStationDataByDate(today);
        double dailyIncome = todayData.stream()
            .mapToDouble(data -> data.getRevenue() != null ? 
                data.getRevenue().doubleValue() : 0.0)
            .sum();
        
        // 计算月收入（当月所有电站的收入）
        List<StationData> monthData = getStationDataByMonth(currentYear, currentMonth);
        double monthlyIncome = monthData.stream()
            .mapToDouble(data -> data.getRevenue() != null ? 
                data.getRevenue().doubleValue() : 0.0)
            .sum();
        
        // 计算年收入（当年所有电站的收入）
        List<StationData> yearData = getStationDataByYear(currentYear);
        double yearlyIncome = yearData.stream()
            .mapToDouble(data -> data.getRevenue() != null ? 
                data.getRevenue().doubleValue() : 0.0)
            .sum();
        
        IncomeStatistics incomeStatistics = new IncomeStatistics();
        incomeStatistics.setDailyIncome(Math.round(dailyIncome * 100.0) / 100.0);
        incomeStatistics.setMonthlyIncome(Math.round(monthlyIncome * 100.0) / 100.0);
        incomeStatistics.setYearlyIncome(Math.round(yearlyIncome * 100.0) / 100.0);
        
        log.info("收入统计计算完成 - 日收入: {}, 月收入: {}, 年收入: {}", 
                dailyIncome, monthlyIncome, yearlyIncome);
        
        return incomeStatistics;
    }
    
    /**
     * 获取社会效益数据
     */
    private SocialBenefit getSocialBenefit() {
        List<StationData> allStationData = getAllStationData();
        
        // 计算总上网电量（MWh）
        double totalUploadPower = allStationData.stream()
            .mapToDouble(data -> data.getGridUploadPower() != null ? 
                data.getGridUploadPower().doubleValue() : 0.0)
            .sum();
        
        // 社会效益计算系数（基于行业标准）
        // 1MWh = 0.4吨标准煤
        double coalCoefficient = 0.4;
        // 1吨标准煤 = 2.62吨CO2
        double co2Coefficient = 2.62;
        // 1吨CO2 = 0.5棵树
        double treeCoefficient = 0.5;
        
        // 计算节约标准煤（万吨）
        double savedCoal = (totalUploadPower * coalCoefficient) / 10000.0;
        
        // 计算CO2减排量（万吨）
        double co2Reduction = (totalUploadPower * coalCoefficient * co2Coefficient) / 10000.0;
        
        // 计算等效植树量（万棵）
        double equivalentTrees = (totalUploadPower * coalCoefficient * co2Coefficient * treeCoefficient) / 10000.0;
        
        SocialBenefit socialBenefit = new SocialBenefit();
        socialBenefit.setSavedCoal(Math.round(savedCoal * 100.0) / 100.0);
        socialBenefit.setCo2Reduction(Math.round(co2Reduction * 100.0) / 100.0);
        socialBenefit.setEquivalentTrees(Math.round(equivalentTrees * 100.0) / 100.0);
        
        return socialBenefit;
    }
}